package com.cltolarva;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import clanalyser.CLAnalyser;
import clanalyser.contract.Clause;
import clanalyser.graph.CLGraph;
import clanalyser.parser.ParsingException;

public class CheckCLConflictTemp {

	public ArrayList<CLMonitor> allMonitors;
	public ArrayList<CLMonitor> activeMonitors;

	public CheckCLConflictTemp(String clFile) {
		
		allMonitors=new ArrayList<CLMonitor>();
		activeMonitors=new ArrayList<CLMonitor>();
		this.makeAllMonitor(clFile);
	}

	public void addMonitor(CLMonitor clm) {

		allMonitors.add(clm);
	}

	public void removeMonitor(CLMonitor clm) {

		allMonitors.remove(clm);
	}

	public void addActiveMonitor(CLMonitor clm) {

		allMonitors.add(clm);
	}

	public void removeActiveMonitor(CLMonitor clm) {

		allMonitors.remove(clm);
	}

	public void makeAllMonitor(String clFile) {

		String[] temp=null;
		String[] temp1=null;
		try {
			// Open the file that is the first
			// command line parameter
			FileInputStream fstream = new FileInputStream(clFile);
			// Get the object of DataInputStream
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			// Read File Line By Line
			while ((strLine = br.readLine()) != null) {
				// Print the content on the console
				
				//System.out.println(strLine);
				temp=strLine.split("@");
				//temp1=temp[0].split("@");
				//System.out.println(temp[0]); 
				//System.out.println(temp[1]);
				
				CLMonitor clm=new CLMonitor(temp[1],temp[0],false);
				
				this.addMonitor(clm);
				
				//System.out.println(strLine);
			}
			// Close the input stream
			in.close();
		} catch (Exception e) {// Catch exception if any
			System.err.println("Error: " + e.getMessage());
		}


	}
	
	public CLMonitor getCLMonitor(String MethodName){
		
		CLMonitor clm=new CLMonitor("tempContract","tempMethod",false);
		for(int i=0;i<this.allMonitors.size();i++){
			
			if(this.allMonitors.get(i).getRelatedMethod().equals(MethodName)){
				
				return (CLMonitor)allMonitors.get(i);
			}
			
		}
		
		return clm;
		
	}
	
	
	public void printRes(){
		
		System.out.println(this.allMonitors.size());
		for(int i=0;i<allMonitors.size();i++){
			
			
			String clFormula=this.allMonitors.get(i).getClContact();
			String relatedMethod=this.allMonitors.get(i).getRelatedMethod();
			System.out.println(clFormula+"--------------->"+relatedMethod);
			
		}
	}
	
	public boolean isConflicting(ArrayList<CLMonitor> activeMonitorsList,String newCL){
		
		CLAnalyser appAnalyser = new CLAnalyser();
		appAnalyser.clearContract();
		
		for(int i=0;i<activeMonitorsList.size();i++){
			
			appAnalyser.addClause(new Clause(activeMonitorsList.get(i).getClContact().toString()));
			System.out.println(activeMonitorsList.get(i).getClContact().toString());
		}
		
		appAnalyser.addClause(new Clause(newCL));
		System.out.println(newCL);
		
		//appAnalyser.addClause(new Clause("[login](P(logout)^F(request)^F(login))"));
		appAnalyser.addActionConflictDefinition("");
		try {
			appAnalyser.AnalyseContract(true);
			
			if(appAnalyser.getGraph().conflictFree()){
				
				System.out.println("Contract is Conflict Free\n");
				
				CLGraph clg=appAnalyser.getGraph();
				
				clg.generateAutomatonForLarva();
				
				//appAnalyser.getGraph().generateAutomatonForLarva();
				
				System.out.println(appAnalyser.getGraph().generateAutomatonForLarva());
				
				return false;
			}
			else{
				System.out.println("Contract has a Conflict\n");
				return true;
			}
			
		} catch (ParsingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return true;
	}
	
	public static void main(String[] args) {
		
		CheckCLConflictTemp ckc=new CheckCLConflictTemp("D:\\testcl.txt");
		
		//ckc.printRes();
		
		//CLMonitor clmm=ckc.getCLMonitor("logout");
		//CLMonitor clmm=ckc.getCLMonitor("login1");
		
		CLMonitor clm1=new CLMonitor("[login](P(logout)^F(request)^F(login))","login",true);
		//CLMonitor clm2=new CLMonitor("[logout]P(login)","logout",true);
		
		ckc.activeMonitors.add(clm1);
		//ckc.activeMonitors.add(clm2);
		
		boolean b=ckc.isConflicting(ckc.activeMonitors,"[logout]F(logout)");
		
		System.out.print("Conflicting: "+b);
		//System.out.print(clmm.getClContact());
	}

}
